#pragma once

#include <set>
#include <atlstr.h>
#include <map>
#include "LogExecutor.h"

using namespace std;

namespace Utility
{
    namespace LoggerLib
    {
        class CLogManager
        {
            typedef set<ELOGLEVEL> LevelSet;
            typedef set<IExecutor*> ExecutorSet;
            typedef map<ELOGEXECUTOR, IExecutor*> ExecutorMap;
            typedef ExecutorMap::value_type ExecutorMapVal;

        public:
            CLogManager();
            virtual ~CLogManager();

            void SetLogLevel(unsigned long dwLevel);
            unsigned long GetLogLevel() const {return m_dwLogLevel;}

            void SetLogExecutorFlag(unsigned long dwFlag);
            unsigned long GetExecutorFlag() const { return m_dwExecutorFlag;}
            
            IExecutor* GetExecutor(ELOGEXECUTOR eType);
            
            int Log(ELOGLEVEL eLevel, ELOGMODULE eModule, const wstring &strLog);

            bool StartAllExecutors();
            bool StartExecutor(ELOGEXECUTOR eType);

            void SetLogFilePath(const wstring &strPath);

        private:
            int CreateAllExecutors();
            void ClearAllExecutors();
            int InvokeExecutors(const LoggingEvent& logEvent);
            void AddActiveExecutor(ELOGEXECUTOR eExecutor);

        private:
            LevelSet m_setLevel;
            ExecutorSet m_setActiveExecutors;
            ExecutorMap m_mapExecutors;

            unsigned long m_dwLogLevel;
            unsigned long m_dwLogModule;
            unsigned long m_dwExecutorFlag;

            /*CAutoSpinLock m_lockLevel;
            CAutoSpinLock m_lockModule;
            CAutoSpinLock m_lockExecutor;*/
        };
    }
}